<!-- 标签管理页面 - 提供标签的增删改查功能，支持标签颜色自定义 -->
<template>
    <div class="tag-list">
        <!-- 示例数据提示 -->
        <el-alert v-if="isUsingSampleData" title="示例数据模式" description="当前显示的是示例数据，因为API调用失败。请检查网络连接或联系管理员。"
            type="warning" :closable="false" show-icon class="sample-data-notice" />

        <!-- 操作区域 - 包含页面标题和新增按钮 -->
        <div class="action-section">
            <div class="section-header">
                <h2>标签管理</h2>
                <div class="header-actions">
                    <!-- 搜索框 -->
                    <div class="search-box">
                        <el-input v-model="searchKeyword" placeholder="搜索标签名称..." clearable @input="handleSearch">
                            <template #prefix>
                                <el-icon>
                                    <Search />
                                </el-icon>
                            </template>
                        </el-input>
                    </div>
                    <el-button type="primary" @click="showAddDialog">
                        <el-icon>
                            <Plus />
                        </el-icon>
                        新增标签
                    </el-button>
                </div>
            </div>
        </div>

        <!-- 标签列表网格布局 -->
        <div class="tags-grid" v-loading="loading" element-loading-text="加载中..." element-loading-spinner="Loading"
            element-loading-background="rgba(255, 255, 255, 0.8)">
            <!-- 标签卡片，循环渲染所有标签 -->
            <div class="tag-card" v-for="tag in tags" :key="tag.id">
                <!-- 标签卡片头部，包含颜色标识和操作按钮 -->
                <div class="tag-header">
                    <!-- 标签颜色标识 -->
                    <div class="tag-color" :style="{ backgroundColor: tag.color }"></div>
                    <!-- 标签操作按钮组 -->
                    <div class="tag-actions">
                        <!-- 编辑按钮 -->
                        <el-button size="small" @click="editTag(tag)">
                            <el-icon>
                                <Edit />
                            </el-icon>
                            编辑
                        </el-button>
                        <!-- 更多操作下拉菜单 -->
                        <el-dropdown @command="handleCommand">
                            <el-button size="small">
                                <el-icon>
                                    <More />
                                </el-icon>
                                更多<el-icon class="el-icon--right">
                                    <ArrowDown />
                                </el-icon>
                            </el-button>
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <!-- 查看文章选项 -->
                                    <el-dropdown-item :command="{ action: 'viewPosts', id: tag.id }">
                                        查看文章
                                    </el-dropdown-item>
                                    <!-- 删除选项 -->
                                    <el-dropdown-item divided :command="{ action: 'delete', id: tag.id }">
                                        删除
                                    </el-dropdown-item>
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                    </div>
                </div>

                <!-- 标签卡片内容区域 -->
                <div class="tag-content">
                    <!-- 标签名称 -->
                    <h3 class="tag-name">{{ tag.name }}</h3>
                    <!-- 标签描述 -->
                    <p class="tag-description">{{ tag.description }}</p>
                    <!-- 标签统计信息 -->
                    <div class="tag-stats">
                        <span class="post-count">{{ tag.postCount }} 篇文章</span>
                        <span class="create-time">{{ formatDate(tag.createTime) }}</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- 新增/编辑标签对话框 -->
        <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑标签' : '新增标签'" width="500px" @close="resetForm">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
                <!-- 标签名称输入框 -->
                <el-form-item label="标签名称" prop="name">
                    <el-input v-model="form.name" placeholder="请输入标签名称" />
                </el-form-item>

                <!-- 标签颜色选择器 -->
                <el-form-item label="标签颜色" prop="color">
                    <el-color-picker v-model="form.color" show-alpha />
                </el-form-item>

                <!-- 标签描述输入框 -->
                <el-form-item label="描述" prop="description">
                    <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入标签描述" />
                </el-form-item>
            </el-form>

            <!-- 对话框底部按钮 -->
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm" :loading="submitting">
                        {{ isEdit ? '更新' : '创建' }}
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
// 导入Vue 3 Composition API核心功能
import { ref, onMounted } from 'vue'
// 导入Vue Router用于页面导航
import { useRouter } from 'vue-router'
// 导入Element Plus组件和消息提示
import { ElMessage, ElMessageBox } from 'element-plus'
// 导入Element Plus图标组件
import { Plus, ArrowDown, Edit, More, Loading, Search } from '@element-plus/icons-vue'
// 导入Element Plus表单类型
import type { FormInstance, FormRules } from 'element-plus'
// 导入API工具函数
import { get, post, put, del, API_PATHS } from '@/utils/api'

// 获取路由实例，用于页面跳转
const router = useRouter()

// 响应式数据定义
const loading = ref(false) // 页面加载状态
const dialogVisible = ref(false) // 对话框显示状态
const isEdit = ref(false) // 是否为编辑模式
const submitting = ref(false) // 表单提交状态
const formRef = ref<FormInstance>() // 表单引用
const isUsingSampleData = ref(false) // 是否使用示例数据
const searchKeyword = ref('') // 搜索关键词

// 表单数据对象
const form = ref({
    id: 0, // 标签ID
    name: '', // 标签名称
    color: '#667eea', // 标签颜色
    description: '' // 标签描述
})

// 表单验证规则配置
const rules: FormRules = {
    name: [
        { required: true, message: '请输入标签名称', trigger: 'blur' },
        { min: 2, max: 20, message: '标签名称长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    color: [
        { required: true, message: '请选择标签颜色', trigger: 'change' }
    ],
    description: [
        { max: 200, message: '描述长度不能超过 200 个字符', trigger: 'blur' }
    ]
}

// 类型定义
interface Tag {
    id: number
    name: string
    color: string
    description: string
    postCount: number
    createTime: string
}

interface TagRequest {
    name: string
    color: string
    description: string
}

interface TagResponse {
    id: number
    name: string
    color: string
    description: string
    postCount: number
    createTime: string
}

interface TagListResponse {
    tags: Tag[]
    total: number
    page: number
    pageSize: number
}

// 示例数据
const sampleTags: Tag[] = [
    {
        id: 1,
        name: 'Vue',
        color: '#42b883',
        description: 'Vue.js 相关技术文章',
        postCount: 12,
        createTime: '2024-12-01T10:00:00Z'
    },
    {
        id: 2,
        name: 'React',
        color: '#61dafb',
        description: 'React 相关技术文章',
        postCount: 8,
        createTime: '2024-12-02T11:00:00Z'
    },
    {
        id: 3,
        name: 'TypeScript',
        color: '#3178c6',
        description: 'TypeScript 相关技术文章',
        postCount: 15,
        createTime: '2024-12-03T12:00:00Z'
    },
    {
        id: 4,
        name: 'JavaScript',
        color: '#f7df1e',
        description: 'JavaScript 相关技术文章',
        postCount: 20,
        createTime: '2024-12-04T13:00:00Z'
    },
    {
        id: 5,
        name: 'CSS',
        color: '#1572b6',
        description: 'CSS 相关技术文章',
        postCount: 10,
        createTime: '2024-12-05T14:00:00Z'
    },
    {
        id: 6,
        name: 'Node.js',
        color: '#339933',
        description: 'Node.js 相关技术文章',
        postCount: 6,
        createTime: '2024-12-06T15:00:00Z'
    }
]

// 使用示例数据的函数
const useSampleData = () => {
    allTags.value = sampleTags
    tags.value = [...sampleTags]
    isUsingSampleData.value = true
    ElMessage.warning('API调用失败，正在使用示例数据')
}

// 标签数据
const allTags = ref<Tag[]>([]) // 存储所有标签数据
const tags = ref<Tag[]>([]) // 当前显示的标签数据

// API调用函数
/**
 * 获取标签列表
 * 从后端API获取所有标签信息
 */
const fetchTags = async () => {
    loading.value = true
    try {
        const response = await get<TagListResponse>(API_PATHS.ADMIN_TAG.LIST, {
            timeout: 10000,
            retry: 3
        })

        if (response && response.success && response.data) {
            allTags.value = response.data.tags
            tags.value = [...response.data.tags]
            isUsingSampleData.value = false
        } else {
            throw new Error('获取标签列表失败')
        }
    } catch (error) {
        console.error('获取标签列表失败:', error)
        useSampleData()
    } finally {
        loading.value = false
    }
}

/**
 * 创建标签
 * @param tagData - 标签数据
 */
const createTagAPI = async (tagData: TagRequest) => {
    try {
        const response = await post<TagResponse>(API_PATHS.ADMIN_TAG.CREATE, tagData, {
            timeout: 10000,
            retry: 3
        })

        if (response && response.success && response.data) {
            ElMessage.success('标签创建成功')
            return response.data
        } else {
            throw new Error('创建标签失败')
        }
    } catch (error) {
        console.error('创建标签失败:', error)
        ElMessage.error('创建标签失败，请重试')
        throw error
    }
}

/**
 * 更新标签
 * @param id - 标签ID
 * @param tagData - 标签数据
 */
const updateTagAPI = async (id: number, tagData: TagRequest) => {
    try {
        const response = await put<TagResponse>(API_PATHS.ADMIN_TAG.UPDATE(id.toString()), tagData, {
            timeout: 10000,
            retry: 3
        })

        if (response && response.success && response.data) {
            ElMessage.success('标签更新成功')
            return response.data
        } else {
            throw new Error('更新标签失败')
        }
    } catch (error) {
        console.error('更新标签失败:', error)
        ElMessage.error('更新标签失败，请重试')
        throw error
    }
}

/**
 * 删除标签
 * @param id - 标签ID
 */
const deleteTagAPI = async (id: number) => {
    try {
        const response = await del(API_PATHS.ADMIN_TAG.DELETE(id.toString()), {
            timeout: 10000,
            retry: 3
        })

        if (response && response.success) {
            ElMessage.success('标签删除成功')
            return true
        } else {
            throw new Error('删除标签失败')
        }
    } catch (error) {
        console.error('删除标签失败:', error)
        ElMessage.error('删除标签失败，请重试')
        throw error
    }
}

// 方法定义

/**
 * 显示新增标签对话框
 * 重置表单并设置为新增模式
 */
const showAddDialog = () => {
    isEdit.value = false
    dialogVisible.value = true
}

/**
 * 编辑标签
 * 将标签数据填充到表单中并设置为编辑模式
 * @param tag - 要编辑的标签对象
 */
const editTag = (tag: any) => {
    isEdit.value = true
    form.value = {
        id: tag.id,
        name: tag.name,
        color: tag.color,
        description: tag.description
    }
    dialogVisible.value = true
}

/**
 * 处理下拉菜单命令
 * 根据命令类型执行相应的操作
 * @param command - 命令对象，包含action和id
 */
const handleCommand = async (command: any) => {
    switch (command.action) {
        case 'viewPosts':
            viewPosts(command.id)
            break
        case 'delete':
            await deleteTag(command.id)
            break
    }
}

/**
 * 查看标签下的文章
 * 跳转到文章列表页面并筛选该标签的文章
 * @param tagId - 标签ID
 */
const viewPosts = (tagId: number) => {
    router.push(`/admin/posts?tag=${tagId}`)
}

/**
 * 删除标签
 * 删除前会显示确认对话框
 * @param id - 要删除的标签ID
 */
const deleteTag = async (id: number) => {
    try {
        await ElMessageBox.confirm('确定要删除这个标签吗？删除后该标签将从所有文章中移除。', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })

        await deleteTagAPI(id)
        await fetchTags() // 重新获取标签列表
    } catch (error) {
        if (error !== 'cancel') {
            console.error('删除标签失败:', error)
        }
    }
}

/**
 * 提交表单
 * 根据是否为编辑模式执行创建或更新操作
 */
const submitForm = async () => {
    if (!formRef.value) return

    try {
        // 验证表单数据
        await formRef.value.validate()
        submitting.value = true

        const tagData: TagRequest = {
            name: form.value.name,
            color: form.value.color,
            description: form.value.description
        }

        if (isEdit.value) {
            await updateTagAPI(form.value.id, tagData)
        } else {
            await createTagAPI(tagData)
        }

        dialogVisible.value = false
        await fetchTags() // 重新获取标签列表
    } catch (error) {
        console.error('提交表单失败:', error)
    } finally {
        submitting.value = false
    }
}

/**
 * 重置表单
 * 清空表单数据并重置验证状态
 */
const resetForm = () => {
    if (formRef.value) {
        formRef.value.resetFields()
    }
    form.value = {
        id: 0,
        name: '',
        color: '#667eea',
        description: ''
    }
}

/**
 * 格式化日期显示
 * @param dateString - ISO格式的日期字符串
 * @returns 格式化后的本地日期字符串
 */
const formatDate = (dateString: string) => {
    const date = new Date(dateString)
    return date.toLocaleDateString('zh-CN')
}

/**
 * 处理搜索输入
 * 调用API搜索标签，如果失败则使用前端过滤作为降级
 */
const handleSearch = async () => {
    if (searchKeyword.value.trim()) {
        try {
            // 调用API搜索标签
            const searchUrl = `${API_PATHS.ADMIN_TAG.SEARCH}?keyword=${encodeURIComponent(searchKeyword.value)}`
            const response = await get(searchUrl, {
                timeout: 8000,
                retry: 2
            })

            if (response && response.success && response.data) {
                // API搜索成功，更新标签列表
                tags.value = response.data
            } else {
                // API搜索失败，使用前端过滤作为降级
                tags.value = allTags.value.filter(tag =>
                    tag.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
                )
            }
        } catch (error) {
            console.error('搜索标签失败，使用前端过滤:', error)
            // API调用失败，使用前端过滤作为降级
            tags.value = allTags.value.filter(tag =>
                tag.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
            )
        }
    } else {
        // 如果没有搜索关键词，显示所有标签
        tags.value = [...allTags.value]
    }
}


// 组件挂载时获取初始数据
onMounted(async () => {
    try {
        await fetchTags()
    } catch (error) {
        console.error('初始化标签列表失败:', error)
        useSampleData()
    }
})
</script>

<style scoped lang="scss">
// 导入标签管理页面样式
@use '../../assets/styles/admin/_tags';
</style>